package io.mft.commons.function.response;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import io.mft.commons.function.FunctionResponseType;
import io.mft.commons.function.IFunctionResponse;
import io.mft.commons.function.response.kv.KVMap;
import io.mft.commons.function.response.kv.KVMapList;
import io.mft.commons.function.response.kv.PageObject;
import io.mft.commons.function.response.kv.PageObject.PageMetadata;
import lombok.Getter;

/**
 * 响应数据对象
 * 
 * @说明：TODO
 * @类型名称：FunctionResponse
 * @创建者: 胡常建
 * @创建时间: 2021年1月27日 下午1:41:59
 * @修改者: 胡常建
 * @修改时间: 2021年1月27日 下午1:41:59
 */

@Getter
public class FunctionResponse implements Serializable, IFunctionResponse {

	

	protected final ResponseWriter responseWriter;
	protected final ResponseReader responseReader;
	private String dsKeyNamespace="";
	
	
	public void setMainDsKey(String mainDsKey) {
		responseWriter.mainDsKey(mainDsKey);
	}
	public void setDsKeyNamespace(String dsKeyNamespace) {
		this.dsKeyNamespace = dsKeyNamespace;
	}
	public FunctionResponse() {
		responseWriter=new DefaultResponseStorage();
		responseReader=(ResponseReader)responseWriter;
	}
	public FunctionResponse(FunctionResponse response) {
		responseWriter=response.responseWriter;
		responseReader=response.responseReader;
		errorInfo=response.getErrorInfo();
		errorNo=response.getErrorNo();
	}
	public FunctionResponse(ResponseWriter responseWriter,ResponseReader responseReader) {
		this.responseWriter=responseWriter;
		this.responseReader=responseReader;
	}
	
	protected static final long serialVersionUID = -2790587935328197196L;
	protected int errorNo;
	protected String errorInfo="";


	public void clear() {
		responseWriter.clear();
		//errorInfo="";
		//errorNo=0;
	}
	public void clear(String key) {
		String ukey=dsKey(key);
		responseWriter.clear(ukey);
	}
	public void result(KVMap value) {
		KVMapList list = new KVMapList();
		list.add(value);
		result(responseReader.mainDsKey(), DsType.map, list);
	}

	public <T> void resultObject(T value) {
		List<T> list=new ArrayList<>();
		list.add(value);
		resultObject(responseReader.mainDsKey(), DsType.map, list);
	}
	public <T> void resultObject(String key,T value) {
		List<T> list=new ArrayList<>();
		list.add(value);
		resultObject(key, DsType.map, list);
	}
	public <T> void resultObject(List<T> value) {
		resultObject(responseReader.mainDsKey(), DsType.list, value);
	}
	public void result(String key, KVMap value) {
		KVMapList list = new KVMapList();
		list.add(value);
		result(key, DsType.map, list);
	}

	public void result(PageObject<KVMap> pager) {
		result(responseReader.mainDsKey(), pager);
	}
	public <T> void resultObject(PageObject<T> pager) {
		resultObject(responseReader.mainDsKey(), pager);
	}
	public void result(String key, PageObject<KVMap> pager) {
		String ukey=dsKey(key);
		responseWriter.write(ukey, pager);
	}
	public <T> void resultObject(String key, PageObject<T> pager) {
		String ukey=dsKey(key);
		responseWriter.writeObject(ukey, pager);
	}
	public List<DsName> getDsName() {
		if (responseReader!=null) {
			return responseReader.dsNames();
		}else {
			return new ArrayList<DsName>();
		}
	}

	public DsName getDsName(String dsName) {
		if (responseReader!=null) {
			String dsKey=dsKey(dsName);
			return responseReader.getDsName(dsKey);
		}else {
			return null;
		}
	}
	public DsName getDefaultDsName() {
		return getDsName(responseReader.mainDsKey());
	}
	public void result(String key, KVMapList value) {
		result(key, DsType.list, value);
	}

	private String dsKey(String key) {
		String ukey=key;
		if (ObjectUtil.isNotEmpty(dsKeyNamespace)) {
			ukey=dsKeyNamespace+"."+key;
		}
		return ukey;
	}
	public void result(String key, DsType type, KVMapList value) {
		String ukey=dsKey(key);
		responseWriter.write(ukey, type, value);
	}

	public <T> void resultObject(String key, DsType type, List<T> value) {
		String ukey=dsKey(key);
		responseWriter.writeObject(ukey, type, value);
	}
	public <T> void resultObject(String key, List<T> value) {
		resultObject(key, DsType.list, value);
	}
	public void result(KVMapList value) {
		result(responseReader.mainDsKey(), value);
	}

	

	public PageObject<KVMap> pageObject() {
		return pageObject(responseReader.mainDsKey());
	}

	public PageObject<KVMap> pageObject(String key) {
		if (responseReader!=null) {
			String dsKey=dsKey(key);
			PageMetadata metadata = responseReader.pageMetadata(dsKey);
			PageObject<KVMap> pager = new PageObject<KVMap>(metadata.getCurrPage(), metadata.getPageSize(),
					metadata.getTotalCount());
			pager.getList().addAll(list(key));
			return pager;
		}else {
			return null;
		}
	}
	public <T> PageObject<T> pageTObject() {
		return pageTObject(responseReader.mainDsKey());
	}
	public <T> PageObject<T> pageTObject(String key) {
		if (responseReader!=null) {
			String dsKey=dsKey(key);
			PageMetadata metadata = responseReader.pageMetadata(dsKey);
			PageObject<T> pager = new PageObject<T>(metadata.getCurrPage(), metadata.getPageSize(),metadata.getTotalCount());
			pager.getList().addAll(listObject(key));
			return pager;
		}else {
			return null;
		}
	}
	public KVMapList list(String key) {
		if (responseReader!=null) {
			String dsKey=dsKey(key);
			return responseReader.list(dsKey);
		}else {
			return null;
		}
	}

	public KVMapList list() {
		return list(responseReader.mainDsKey());
	}
	public <T> List<T> listObject() {
		return listObject(responseReader.mainDsKey());
	}
	public <T> List<T> listObject(String key) {
		String dsKey=dsKey(key);
		List<T> list=responseReader.listObject(dsKey);
		return list;
	}
	@Override
	public String toString() {
		return JSONUtil.toJsonStr(this);
	}

	public KVMap data() {
		return data(responseReader.mainDsKey());
	}

	public KVMap data(String key) {
		List<KVMap> list=list(key);
		if (ObjectUtil.isNotNull(list)&&list.size()>0) {
			return list.get(0);
		} else {
			return null;
		}
	}
	public <T> T dataObject() {
		return dataObject(responseReader.mainDsKey());
	}
	public <T> T dataObject(String key) {
		List<T> list=listObject(key);
		if (ObjectUtil.isNotNull(list)&&list.size()>0) {
			return list.get(0);
		} else {
			return null;
		}
	}
	@Override
	public FunctionResponseType responseType() {
		return FunctionResponseType.kv;
	}

	public void setErrorInfo(String errorInfo) {
		this.errorInfo = errorInfo;
	}

	public void setErrorNo(int errorNo) {
		this.errorNo = errorNo;
	}
}
